(in-package :nondestructive)

(defun xbox ()
  (make-instance 'd:multi-argument-box
                 :children (list (make-instance 'd:argument
                                                :quantity nil))))

(defun p (problem answer numops &optional hints)
  (declare (ignore answer numops))
  `(nondestructive :tree ,(p:parse-old problem (xbox))
                   :guidedp ,hints))

(defun 1-1-even ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(* (+ 5 7) 8))
                    :instruction-title "Evaluate an Expression"
                    :instruction-body "To evaluate an expression find an operation with all numbers, evaluate the operation, and repeat until there are no more operations."
                    :guidedp t)
   (p '(- 9 (* 4 2)) '(1) 2)
   (p '(* (- 9 4) 2) '(10) 2)
   (p '(- (* 8 7) 13) '(43) 2)
   (p '(* 9 (+ 4 2)) '(54) 2)
   (p '(* (/ 36 2) 6) '(108) 2)
   (p '(- (- 16 (* 3 2)) 4) '(6) 3)
   (p '(- 16 (- (* 3 2) 4)) '(14) 3)
   (p '(* (+ 10 6) (- 11 7)) '(64) 3)
   (p '(+ (* 6 (- 11 3)) 10) '(58) 3)
   (p '(/ 100 (- (/ 20 5) 3)) '(100) 3)
   (p '(/ 100 (/ 20 (- 5 3))) '(10) 3)
   (p '(- (/ (- 63 8) (+ 3 8)) 2) '(3) 4)
   (p '(* 5 (/ (- 19 7) (+ 5 1))) '(10) 4)))

(defun 1-1-odd ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(+ 5 (* 7 8)))
                    :instruction-title "Evaluate an Expression"
                    :instruction-body "To evaluate an expression find an operation with all numbers, evaluate the operation, and repeat until there are no more operations."
                    :guidedp t)
   (p '(* (+ 4 9) 5) '(65) 2)
   (p '(+ (* 9 5) 4) '(49) 2)
   (p '(- (* 5 2) 11) '(-1) 2)
   (p '(* (- 11 5) 2) '(12) 2)
   (p '(- (* 7 6) 19) '(23) 2)
   (p '(* (+ 2 5) 8) '(56) 2)
   (p '(* (/ 54 3) 2) '(36) 2)
   (p '(/ 54 (* 3 2)) '(9) 2)
   (p '(- (- 17 (* 4 3)) 2) '(3) 3)
   (p '(* (+ 14 6) (- 9 2)) '(140) 3)
   (p '(+ 14 (* 6 (- 9 2))) '(56) 3)
   (p '(- (/ 200 (/ 50 2)) 7) '(1) 3)
   (p '(- (/ (/ 200 50) 2) 7) '(-5) 3)
   (p '(- 19 (/ (- 25 7) (+ 5 4))) '(17) 4)
   (p '(/ 28 (/ (* 8 6) (+ 5 7))) '(7) 4)))

(defun 1-1-alt ()
  (list
   'exp:subsequence
   (p '(* (+ 4 7) 8) '(88) 2 t)
   (p '(- 11 (* 5 2)) '(1) 2)
   (p '(* (- 9 3) 3) '(18) 2)
   (p '(- (* 8 6) 11) '(37) 2)
   (p '(* 7 (+ 3 4)) '(49) 2)
   (p '(* (/ 16 2) 7) '(56) 2)
   (p '(- (- 16 (* 4 2)) 4) '(4) 3)
   (p '(- 16 (- (* 4 2) 4)) '(12) 3)
   (p '(* (+ 12 4) (- 9 5)) '(64) 3)
   (p '(+ (* 6 (- 10 3)) 8) '(50) 3)
   (p '(/ 80 (- (/ 30 6) 4)) '(80) 3)
   (p '(/ 50 (/ 40 (- 7 3))) '(5) 3)
   (p '(- (/ (- 44 8) (+ 3 3)) 2) '(4) 4)
   (p '(* 8 (/ (- 22 7) (+ 2 3))) '(24) 4)))

(defun 1-2-odd ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(+ 5 (4)))
                    :instruction-title "Input Boxes"
                    :instruction-body "Some diagrams to be evaluated have input boxes with just a number that feed into the rest of the diagram."
                    :guidedp t)
   (p '(+ (93) 5) '(98) 2)
   (p '(- (/ 24 (12)) 1) '(1) 3)
   (p '(* (- (37) 19) 2) '(36) 3)
   (p '(* (- (31) 31) 4) '(0) 3)
   (p '(* 7 (11)) '(77) 2)
   (p '(/ 40 (5)) '(8) 2)
   (p '(/ (+ 5 (95)) 2) '(50) 3)
   (p '(/ (+ (0) 7) 3) '(7/3) 3)))

(defun 1-2-even ()
  (list
   'exp:subsequence
   (p '(+ 5 (6)) '(11) 2 t)
   (p '(+ (8) 5) '(13) 2)
   (p '(+ (/ 72 (9)) 5) '(13) 3)
   (p '(* (- (80) 31) 2) '(98) 3)
   (p '(* 9 (13)) '(117) 2)
   (p '(/ 30 (90)) '(1/3) 2)
   (p '(/ 40 (60)) '(2/3) 2)
   (p '(/ (+ (5) 7) 3) '(4) 3)))

(defun 1-7-odd ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(= (+ x 3) 8) (xbox))
                    :instruction-title "Finding Input Values"
                    :instruction-body "Sometimes a diagram contains an input box without a number but at the bottom of the diagram there is a box with the value of the diagram. Then you must invert the diagram to find the value of the input box."
                    :guidedp t)
   (p '(= (- x 10) 17) '(= x 27) 2)
   (p '(= (+ x 4) 13) '(= x 9) 2)
   (p '(= (* 5 x) 90) '(= x 18) 2)
   (p '(= (/ x 3) 21) '(= x 63) 2)
   (p '(= (- x 16) 7) '(= x 23) 2)
   (p '(= (- x 32) 95) '(= x 127) 2)
   (p '(= (+ x 54) 74) '(= x 20) 2)
   (p '(= (+ x 91) 87) '(= x -4) 2)
   (p '(= (* 12 x) 48) '(= x 4) 2)
   (p '(= (/ x 7) 5) '(= x 35) 2)
   (p '(= (/ x 10) 100) '(= x 1000) 2)
   (p '(= (+ x 5) 4) '(= x -1) 2)
   (p '(= (- x 94) 362) '(= x 456) 2)
   (p '(= (+ x 1984) 2001) '(= x 17) 2)
   (p '(= (/ x 3) 51) '(= x 153) 2)
   (p '(= (* 3 x) 51) '(= x 17) 2)
   (p '(= (* 17 x) 51) '(= x 3) 2)
   (p '(= (/ x 5) 50) '(= x 250) 2)
   (p '(= (* 6 x) 2) '(= x 1/3) 2)
   (p '(= (* 2/3 x) 6) '(= x 9) 2)
   (p '(= (* 3/5 x) 30) '(= x 50) 2)
   (p '(= (* 7 x) 28) '(= x 4) 2)
   (p '(= (+ x 2/3) 5/3) '(= x 1) 2)
   (p '(= (- x 3/4) 7/4) '(= x 5/2) 2)))

(defun 1-7-even ()
  (list
   'exp:subsequence
   (p '(= (+ x 5) 17) '(= x 12) 2 t)
   (p '(= (- x 8) 13) '(= x 21) 2)
   (p '(= (+ x 9) 21) '(= x 12) 2)
   (p '(= (* 6 x) 66) '(= x 11) 2)
   (p '(= (* 1/5 x) 23) '(= x 115) 2)
   (p '(= (- x 17) 8) '(= x 25) 2)
   (p '(= (- x 45) 89) '(= x 134) 2)
   (p '(= (+ x 43) 91) '(= x 48) 2)
   (p '(= (+ x 80) 422) '(= x 342) 2)
   (p '(= (* 15 x) 300) '(= x 20) 2)
   (p '(= (* 4 x) 100) '(= x 25) 2)
   (p '(= (* 1/9 x) 50) '(= x 450) 2)
   (p '(= (* 1/10 x) 1000) '(= x 10000) 2)
   (p '(= (+ x 7) 5) '(= x -2) 2)
   (p '(= (- x 61) 365) '(= x 426) 2)
   (p '(= (+ x 1066) 1776) '(= x 710) 2)
   (p '(= (* 1/3 x) 55) '(= x 165) 2)
   (p '(= (* 3 x) 54) '(= x 18) 2)
   (p '(= (* 18 x) 54) '(= x 3) 2)
   (p '(= (* 1/19 x) 50) '(= x 950) 2)
   (p '(= (* 8 x) 4) '(= x 1/2) 2)
   (p '(= (* 3/2 x) 6) '(= x 4) 2)
   (p '(= (+ x 3/5) 13/5) '(= x 2) 2)
   (p '(= (- x 2/3) 14/3) '(= x 16/3) 2)))

(defun 2-1 ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(+ 4 -3))
                    :instruction-title "Adding Negative Numbers"
                    :instruction-body "The absolute value is the positive version of a number. For numbers with the same sign, add the absolute values. The answer has the same sign. For opposite signs, subtract the absolute values and use the sign of the biggest number."
                    :guidedp t)
   `(nondestructive :tree ,(p:parse-old '(+ -3 -4))
                    :instruction-title  "Adding Negative Numbers"
                    :instruction-body "The absolute value is the positive version of a number. For numbers with the same sign, add the absolute values. The answer has the same sign. For opposite signs, subtract the absolute values and use the sign of the biggest number."
                    :guidedp t)
   (p '(+ 5 -2) '(3) 1)
   (p '(+ 6 -4) '(2) 1)
   (p '(+ 2 -5) '(-3) 1)
   (p '(+ 13 -8) '(5) 1)
   (p '(+ 3 -7) '(-4) 1)
   (p '(+ -3 -2) '(-5) 1)
   (p '(+ -13 -4) '(-17) 1)
   (p '(+ -4 -5) '(-9) 1)
   (p '(+ -8 -9) '(-17) 1)
   (p '(+ 0 -3) '(-3) 1)
   (p '(+ -3 5) '(2) 1)
   (p '(+ -4 1) '(-3) 1)
   (p '(+ -13 15) '(2) 1)
   (p '(+ -27 1) '(-26) 1)
   (p '(+ -11 35) '(24) 1)))

(defun 2-3 ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(- -4 3))
                    :instruction-title "Subtracting Signed Numbers"
                    :instruction-body "Change subtracting to adding the opposite. Then follow the rules for adding signed numbers."
                    :guidedp t)
   (p '(- 35 200) '(-165) 1)
   (p '(- 14 -17) '(31) 1)
   (p '(- -11 -2) '(-9) 1)
   (p '(- -99 59) '(-158) 1)
   (p '(- -241 -42) '(-199) 1)
   (p '(- 158 -115) '(273) 1)
   (p '(- 5/7 -2/7) '(1) 1)
   (p '(- 0 -15) '(15) 1)
   (p '(- 154 (- 43 28)) '(139) 2)
   (p '(- 314 (- 58 70)) '(326) 2)
   (p '(- (- 33 45) (- 64 78)) '(2) 3)
   (p '(- (- 13 5) (- -2 6)) '(16) 3)
   (p '(+ (- 1066 1492) 1984) '(1558) 2)
   (p '(- (- 8 -3) (- 4 -6)) '(1) 3)
   (p '(+ (+ (- 1 2) (- 4 8)) 16) '(11) 4)
   (p '(- (+ (- (- 45 7) 58) 11) 21) '(-30) 4)
   (p '(- (+ (- (+ (- 19 2) 23) 54) 34) 29) '(-9) 5)
   (p '(- (+ (- (+ (- 200 195) 71) 66) 18) 29) '(-1) 5)))

(defun 2-4 ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(* -3 -7))
                    :instruction-title "Multiplying Signed Numbers"
                    :instruction-body '("Negative times negative is positive."
                                        "Positive times negative is negative."
                                        "Negative times positive is negative.")
                    :guidedp t)
   `(nondestructive :tree ,(p:parse-old '(* -5 8))
                    :instruction-title "Multiplying Signed Numbers"
                    :instruction-body '("Negative times negative is positive."
                                        "Positive times negative is negative."
                                        "Negative times positive is negative.")
                    :guidedp t)
   (p '(* 10 -7) '(-70) 1)
   (p '(* -5 -9) '(45) 1)
   (p '(* -6 8) '(-48) 1)
   (p '(* -2/3 6) '(-4) 1)
   (p '(* -72 1) '(-72) 1)
   (p '(* -1 -200) '(200) 1)
   (p '(* -53 0) '(0) 1)
   (p '(* (* -3 -5) -7) '(-105) 2)
   (p '(* (* -2 5) -8) '(80) 2)
   (p '(* (* 4 -7) 2) '(-56) 2)
   (p '(* (* (* -1 5) -3) -2) '(-30) 3)))

(defun 2-5 ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(/ -54 6))
                    :instruction-title "Division Of Signed Numbers"
                    :instruction-body '("Negative divided by negative is positive."
                                        "Positive divided by negative is negative."
                                        "Negative divided by positive is negative.")
                    :guidedp t)
   `(nondestructive :tree ,(p:parse-old '(/ -54 -3))
                    :instruction-title "Division Of Signed Numbers"
                    :instruction-body '("Negative divided by negative is positive."
                                        "Positive divided by negative is negative."
                                        "Negative divided by positive is negative.")
                    :guidedp t)
   (p '(/ -21 7) '(-3) 1)
   (p '(/ 21 -7) '(-3) 1)
   (p '(/ -21 -7) '(3) 1)
   (p '(/ -26 2) '(-13) 1)
   (p '(/ 51 -3) '(-17) 1)
   (p '(/ -55 -11) '(5) 1)
   (p '(/ 1000 -10) '(-100) 1)
   (p '(/ (- 7 19) -3) '(4) 2)
   (p '(/ (- 13 37) -2) '(12) 2)
   (p '(/ 45 (- 5 14)) '(-5) 2)
   (p '(/ (- 32 4) (- 8 15)) '(-4) 3)
   (p '(/ (* 8 -3) -6) '(4) 2)
   (p '(/ (* -3 10) 5) '(-6) 2)
   (p '(/ 10 -1) '(-10) 1)
   (p '(/ -10 -1) '(10) 1)
   (p '(/ 0 10) '(0) 1)
   (p '(/ 0 -10) '(0) 1)
   (p '(/ 15 (5)) '(3) 2)
   (p '(/ 15 (-3)) '(-5) 2)
   (p '(/ (5) -30) '(-1/6) 2)
   (p '(/ (-3) -30) '(1/10) 2)
   (p '(/ (+ (-2) 5) (+ (-2) 3)) '(3) 3)
   (p '(/ (+ (5) 5) (+ (5) 3)) '(5/4) 3)
   (p '(/ (- 5 (2)) (- 3 (2))) '(3) 3)
   (p '(/ (- 5 (5)) (- 3 (5))) '(0) 3)
   (p '(/ (- 5 (-3)) (- 3 (-3))) '(4/3) 3)))

(defun 2-6-odd ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(+ 3 (+ (* 2 x) 7)) (xbox))
                    :instruction-title "The Combine Operator"
                    :instruction-body "One can collapse two boxes with + or - into a single box and preserve the value of the diagram. One can do the same thing with two boxes with * or /."
                    :guidedp t)
   (p '(+ (+ 4 x) 3) '((+ x 7)) 2)
   (p '(+ (+ 6 x) 7) '((+ x 13)) 2)
   (p '(- (+ 5 x) 3) '((+ x 2)) 2)
   (p '(+ (+ -8 x) 4) '((+ x -4)) 2)
   (p '(+ (- 15 x) 9) '((- 24 x)) 2)
   (p '(- (- 6 x) 37) '((- -31 x)) 2)
   (p '(- (- -19 x) 22) '((- -41 x)) 2)
   (p '(+ (+ 9 (* 7 x)) 3) '((+ 12 (* 7 x))) 2)
   (p '(+ (- -18 (* 3 x)) 7) '((- -11 (* 3 x) )) 2)
   (p '(* (* 5 x) 7) '((* 35 x)) 2)
   (p '(* (* 3 x) -8) '((* -24 x)) 2)
   (p '(* (* 20 x) 1/5) '((* 4 x)) 2)
   (p '(* -1/8 (* 56 x)) '((* -7 x)) 2)
   (p '(* (* 9 x) 1/9) '((* 1 x)) 2)
   (p '(/ (* 54 x) 9) '((* 6 x)) 2)
   (p '(/ (* -88 x) 11) '((* -8 x)) 2)
   (p '(/ (* 1000 x) -10) '((* -100 x)) 2)
   (p '(/ (* -37 x) -1) '((* 37 x)) 2)
   (p '(/ (* -19 x) -19) '((* 1 x)) 2)))

(defun 2-6-even ()
  (list
   'exp:subsequence
   (p '(* (* 12 x) 1/4) '((* x 3)) 2 t)
   (p '(+ (+ 5 x) 4) '((+ x 9)) 2)
   (p '(+ (+ 8 x) 13) '((+ 21 x)) 2)
   (p '(- (+ 7 x) 9) '((- x 2)) 2) 
   (p '(+ (+ -3 x) 11) '((+ x 8)) 2)
   (p '(+ (- 16 x) 5) '((- 21 x)) 2)
   (p '(- (- 12 x) 15) '((- -3 x)) 2)
   (p '(- (- -2 x) 71) '((- -73 x)) 2)
   (p '(+ (- -13 x) 13) '((- 0 x)) 2)
   (p '(+ (+ 14 (* 3 x)) 21) '((+ 35 (* 3 x))) 2)
   (p '(- (- 8 (* 5 x)) 13) '((- -5 (* 5 x))) 2)
   (p '(* (* 7 x) 9) '((* x 63)) 2)
   (p '(* (* 5 x) -13) '((* x -65)) 2)
   (p '(* (* 30 x) 1/6) '((* x 5)) 2)
   (p '(* -1/3 (* 21 x)) '((* x -7)) 2)
   (p '(* (* 1/3 x) 3) '((* x 1)) 2)
   (p '(/ (* 86 x) 2) '((* x 43)) 2)
   (p '(/ (* -18 x) 9) '((* x -2)) 2)
   (p '(/ (* 100 x) -5) '((* x -20)) 2)
   (p '(/ (* -1 x) -1) '((* x 1)) 2)))

(defun 2-7-odd ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(= (+ (* 2 x) 3) 19) (xbox))
                    :instruction-title "More On Invert" 
                    :instruction-body "The invert operation can be repeated."
                    :guidedp t)
   `(nondestructive :tree ,(p:parse-old '(= (- 10 x) 2) (xbox))
                    :instruction-title "More On Invert"
                    :instruction-body "There is a special case when the operator is - and the black tile is on the right."
                    :guidedp t)
   (p '(= (+ (* 1/3 x) 5) 7) '(= x 6) 4)
   (p '(= (- (* 1/2 x) 8) 3) '(= x 22) 4)
   (p '(= (+ (* 5 x) 4) 39) '(= x 7) 4)
   (p '(= (- (* 3 x) 7) 26) '(= x 11) 4)
   (p '(= (+ (* -1/6 x) 5) 8) '(= x -18) 4)
   (p '(= (- (* -1/4 x) 9) 16) '(= x -100) 4)
   (p '(= (- 13 (* 4 x)) 25) '(= x -3) 4)
   (p '(= (- 8 (* 1/7 x)) -9) '(= x 119) 4)
   (p '(= 53 (+ (* 5 x) 11)) '(= x 42/5) 4)
   (p '(= (- 17 x) 25) '(= x -8) 2)
   (p '(= 71 (- 4 x)) '(= x -67) 2)
   (p '(= (+ (* 2/3 x) 6) 18) '(= x 18) 4)
   (p '(= (+ -21 (* 4 x)) 10) '(= x 31/4) 4)
   (p '(= (- -4/3 x) -1/3) '(= x -1) 2)))

(defun 2-7-even ()
  (list
   'exp:subsequence
   (p '(= (+ (* 3/2 x) 4) -9) '(= x -26/3) 4 t)
   (p '(= (- 5 x) -7) '(= x 12) 2 t)
   (p '(= (+ (* 1/5 x) 3) 9) '(= x 30) 4)
   (p '(= (- (* 1/4 x) 7) 2) '(= x 36) 4)
   (p '(= (+ (* 6 x) 5) 53) '(= x 8) 4)
   (p '(= (- (* 2 x) 13) 95) '(= x 54) 4)
   (p '(= (+ (* -1/3 x) 6) 10) '(= x -12) 4)
   (p '(= (- (* -1/2 x) 7) 23) '(= x -60) 4)
   (p '(= (- 6 (* 3 x)) 39) '(= x -11) 4)
   (p '(= (- 11 (* 9 x)) -43) '(= x 6) 4)
   (p '(= 22 (+ 4 (* 5 x))) '(= x 18/5) 4)
   (p '(= (- 15 x) 41) '(= x -26) 2)
   (p '(= 13 (- 17 x)) '(= x 4) 2)
   (p '(= (+ (* 3/4 x) 12) 36) '(= x 32) 4)
   (p '(= (+ -8 (* 3 x)) 6) '(= x 14/3) 4)
   (p '(= (- -2/5 x) 1/5) '(= x -3/5) 2)))

(defun 3-1 ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(+ (* 5 (+ x 2)) 9) (xbox))
                    :instruction-title "The Reorder Operator" 
                    :instruction-body "One can transform a diagram so that a + or - box above a * box moves to below the * box without changing the value of the diagram."
                    :guidedp t)
   (p '(+ (* 3 (+ x 5)) 11) '((+ 26 (* 3 x))) 4)
   (p '(+ (* 7 (+ 6 x)) 8) '((+ (* 7 x) 50)) 4)
   (p '(+ (* 2 (+ (* 3 x) 8)) 40) '((+ (* 6 x) 56)) 6)
   (p '(- (* 9 (+ 4 (* 8 x))) 6) '((+ (* 72 x) 30)) 6)
   (p '(+ 100 (* 6 (+ (* 4 x) 9))) '((+ (* 24 x) 154)) 6)))

(defun 3-2 ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(- 9 (* 2 (- x 4))) (xbox))
                    :instruction-title "Reorder And Subtraction"
                    :instruction-body "You can also reorder if a - box feeds into a * box."
                    :guidedp t)
   (p '(* 3 (+ x 7)) '((+ (* 3 x) 21)) 2)
   (p '(* 7 (- (* 3 x) 8)) '((- (* 21 x) 56)) 4)
   (p '(* -5 (- 6 x)) '((- -30 (* -5 x))) 2)
   (p '(* 6 (+ 9 (* 7 x))) '((+ 54 (* 42 x))) 4)
   (p '(* 28 (+ (* 1/4 x) 1/7)) '((+ (* 7 x) 4)) 4)
   (p '(* 2/3 (+ (* 4 x) 3/4)) '((+ (* 8/3 x) 1/2)) 4)
   (p '(- 8 (* 5 (- 4 (* 6 x)))) '((+ -12 (* 30 x))) 7)
   (p '(- 11 (* 1 (+ (* 5 x) 3))) '((+ 8 (* -5 x))) 7)))

(defun 3-4 ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(- (* 7 x) (* 5 x)) (xbox))
                    :instruction-title "More On Input Boxes"
                    :instruction-body "Sometimes an input box will have more than one arrow connecting it to other boxes. If the boxes connected to it are * boxes, and they are connected to a + or - box, then Combine can be used to simplify the diagram."
                    :guidedp t)
   `(nondestructive :tree ,(p:parse-old '(+ (* 5 x) (- 6 (* 2 x))) (xbox))
                    :instruction-title "More On Input Boxes"
                    :instruction-body "Combine works when there is an extra + or - box, too."
                    :guidedp t)
   (p '(+ (* 5 x) (* 9 x)) '((* 14 x)) 2)
   (p '(- (* 8 x) (* 3 x)) '((* 5 x)) 2)
   (p '(- (* 9 x) (* 8 x)) '((* 1 x)) 2)
   (p '(+ (+ (* 3 x) (* 7 x)) 8) '((+ (* 10 x) 8)) 2)
   (p '(+ (+ (* 5 x) 9) (* 7 x)) '((+ (* 12 x) 9)) 2)
   (p '(- (- (* 3 x) 2) (* 8 x)) '((- (* -5 x) 2)) 2)
   (p '(+ (- -4 (* 5 x)) (* 11 x)) '((+ -4 (* 6 x))) 2)
   (p '(- (+ (* -6 x) 13) (* 7 x)) '((+ 13 (* -13 x))) 2)
   (p '(+ (* 5 x) (* 3 (- x 2))) '((- (* 8 x) 6)) 4)
   (p '(- 7 (* 4 (+ (* 2 x) 5))) '((- -13 (* 8 x))) 7)
   (p '(- (* 2 (+ (* 3 x) 4)) (* 5 x)) '((+ (* 1 x) 8)) 6)))

(defun 3-5 ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(+ (* 2 x) x) (xbox))
                    :instruction-title "More On Input Boxes Part II"
                    :instruction-body "If an input box is connected to a + or - box then you need to do an extra step before you can use combine."
                    :guidedp t)
   `(nondestructive :tree ,(p:parse-old '(- (+ (* 5 x) 3) (- 6 (* 2 x))) (xbox))
                    :instruction-title "More On Input Boxes Part II"
                    :instruction-body "When two + or - boxes are connected via a + box then they can be combined. If they are connected via a - box, the connecting - must be \"undone\" first."
                    :guidedp t)
   (p '(+ (* -8 (- (* 9 x) 7)) (- (* 72 x) 57)) '(-1) 10)
   (p '(- (* 6 x) x) '((* 5 x)) 3)
   (p '(+ (* 4 (+ (* 3 x) 2)) (* 6 (+ (* 5 x) 8))) '((+ (* 42 x) 56)) 12)
   (p '(+ (* 2 (- x 5)) (* 5 (- 4 (* 2 x)))) '((+ (* -8 x) 10)) 10)
   (p '(- (* 6 x) (- x 1)) '((+ (* 5 x) 1)) 4)
   (p '(- (* 8 (+ (* 2 x) 3)) (* 4 (+ (* 3 x) 6))) '((* 4 x)) 13)
   (p '(- (* 3 (+ 6 (* 5 x))) (* 7 (- (* 2 x) 1))) '((+ (* 1 x) 25)) 13)
   (p '(- (* -6 (- x 5)) (* 2 (- 7 (* 3 x)))) '(16) 13)
   (p '(- (* 8 (+ x 4)) (- x 5)) '((+ (* 7 x) 37)) 8)
   (p '(- (* 1/4 (+ (* 12 x) 20)) (* 1/5 (- 30 (* 15 x)))) '((+ (* 6 x) -1)) 13)))

(defun 4-1 ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(= (+ (* 2 x) (* 6 x)) 56) (xbox))
                    :instruction-title "Find The Value Of The Input Box"
                    :instruction-body "Use the knowledge you have acquired from the previous sections to find the value of the input box."
                    :guidedp t)
   (p '(= (- (* 7 x) (* 4 x)) 15) '(= x 5) 4)
   (p '(= (+ (+ (* 3 x) (* 4 x)) 8) 22) '(= x 2) 6)
   (p '(= (+ (- (* 10 x) (* 7 x)) 18) 6) '(= x -4) 6)
   (p '(= (+ (- (* 5 x) (* 7 x)) 21) 27) '(= x -3) 6)
   (p '(= (+ (+ (* 7 x) 3) (* 3 x)) 63) '(= x 6) 6)
   (p '(= (- (- (* 9 x) 14) (* 5 x)) -10) '(= x 1) 6)
   (p '(= (- (* 10 x) x) 90) '(= x 10) 5)
   (p '(= (- (- (* 7 x) 4) (* 6 x)) 5) '(= x 9) 6)
   (p '(= (+ (+ (+ (* 2 x) (* 3 x)) 4) (* 5 x)) 34) '(= x 3) 8)
   (p '(= (+ (+ (+ (* 3 x) 4) (* 5 x)) (* 6 x)) 32) '(= x 2) 8)))

(defun 4-2 ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(= (+ (* 6 (- x 2)) (* 5 x)) 43) (xbox))
                    :instruction-title "Harder Diagrams"
                    :instruction-body "Use the knowledge you have acquired from the previous sections to find the value of the input box."
                    :guidedp t)
   (p '(= (+ (* 7 x) (* 3 x)) 40) '(= x 4) 4)
   (p '(= (- (* 4 x) (* 11 x)) 49) '(= x -7) 4)
   (p '(= (+ (+ (* 16 x) 3) (* 4 x)) 103) '(= x 5) 6)
   (p '(= (- (- (* 7 x) 8) (* 4 x)) 25) '(= x 11) 6)
   (p '(= (- (+ (* -5 x) 17) (* 8 x)) 56) '(= x -39/13) 6)
   (p '(= 58 (+ (- 6 (* 14 x)) (* 12 x))) '(= x -26) 6)
   (p '(= (- (+ (* 8 x) 5) (* 7 x)) 22) '(= x 17) 6)
   (p '(= (- (+ (* 20 x) 84) (* 8 x)) 0) '(= x -7) 6)
   (p '(= (+ (+ x 21) (* 4 x)) -33) '(= x -54/5) 7)
   (p '(= (+ (+ (- (* 2 x) (* 5 x)) 13) (* 9 x)) 67) '(= x 9) 8)
   (p '(= (- (* 5 (+ x 3)) (* 2 x)) -21) '(= x -12) 8)
   (p '(= (+ (* 2 (- (* 3 x) 7)) (* 4 x)) 26) '(= x 4) 10)
   (p '(= (+ (* 5 x) (* 3 (+ x 4))) 28) '(= x 2) 8)
   (p '(= (- (* 7 x) (* 4 (- 2 (* 3 x)))) -27) '(= x -1) 11)
   (p '(= (- (* 7 x) (+ 5 (* 6 x))) 4) '(= x 9) 7)
   (p '(= (+ (- 12 (* 7 (- x 4))) x) -2) '(= x 7) 12)
   (p '(= (- (* 2 (+ x 3)) (* 5 (- x 1))) 32) '(= x -7) 13)
   (p '(= 55 (+ (* 3 (- (* 2 x) 1)) (* 2 (+ x 5)))) '(= x 6) 14)
   (p '(= 0 (+ (* 4 (- 6 x)) (* 7 x))) '(= x -8) 8)
   (p '(= (- (* 3 (+ x 2)) (- x 1)) 17) '(= x 5) 12)))

(defun 4-3 ()
  (list
   'exp:subsequence
   `(nondestructive :tree ,(p:parse-old '(= (+ (* 3 x) 55) (* 8 x)) (xbox))
                    :instruction-title "The Subtract Operation"
                    :instruction-body "When two boxes feed into the same result box at the bottom this means they are equal. One can transform this into a diagram we can operate on by subtracting the right box from the left and saying the difference is 0."
                    :guidedp t)
   (p '(= (+ (* 5 x) 27) (* 2 x)) '(= x -9) 7)
   (p '(= (- (* 6 x) 28) (* 8 x)) '(= x -14) 7)
   (p '(= (* 9 x) (- (* 4 x) 65)) '(= x -13) 8)
   (p '(= (- 55 (* 3 x)) (* 8 x)) '(= x 5) 7)
   (p '(= (* 5 x) (- 48 x)) '(= x 8) 9)
   (p '(= (- (* 10 x) 51) (* 7 x)) '(= x 17) 7)
   (p '(= (+ (* 29 x) 56) (* 27 x)) '(= x -28) 7)
   (p '(= (* -6 x) (- x 70)) '(= x 10) 9)
   (p '(= (* 9 x) (+ 34 (* 8 x))) '(= x 34) 8)
   (p '(= (* 7 x) (- -16 (* 9 x))) '(= x -1) 8)
   (p '(= (+ (* 5 x) 8) (+ (* 7 x) 8)) '(= x 0) 10)
   (p '(= (- (* 2 x) 5) (+ (* 3 x) 4)) '(= x -9) 10)
   (p '(= (- (+ (* 6 x) 7) (* 2 x)) (- (+ 3 (* 2 x)) 9)) '(= x -13/2) 14)
   (p '(= (* 4 (+ x 3)) (* 6 x)) '(= x 6) 9)
   (p '(= (* 3 (- 9 x)) (* 2 (+ x -4))) '(= x 7) 12)
   (p '(= (+ (* 3 x) (* 3 (- 1 x))) (- x 17)) '(= x 20) 11)
   (p '(= (* 2 (- 1 (* 3 (+ x 2)))) (- x 1)) '(= x -9/7) 22)))

;;;;;;; minimal curriculum

;; 1. Propogating down.  one never has to perform graph surgery in this 
;; case -- just make it a more elaborate set of problems of the sort in 
;; 1-2.

;; 2. Propogating values up.   This can only be done when there is line 
;; of operations and no graph paths merging.   Section 2-7 is a fair 
;; example of this case.

;; 3. Collapse or whatever we call it.   Graphs with one or more merges 
;; of paths but  nothing else other wise lines of propogation.

;; 4. Combine or whatever we call it in combination with collapsing. 
;; It is only required for collapsing.

;; 5. Switch or whatever we call it in combination with collapsing.   It 
;; is only required for collapsing.

;; 6. Reorder or whatever we call it on combination with switch and 
;; collapsing.   It is only required for switching.

(defun propogate-down ()
  `(exp:subsequence
    ,@(loop for tree in (pg:expand-and-fill-n-times 50 :top
                                                    '(n oo (n oo x))
                                                    '(n oo (n oo (n oo x)))
                                                    '(n oo (n oo (n oo (n oo x))))
                                                    '((n oo (n oo x))
                                                      oo
                                                      (n oo (n oo x))))
         for i from 0
         collect `(nondestructive :tree ,tree
                                  :guidedp ,(zerop i)))))

(defun propogate-up ()
  `(exp:subsequence
    ,@(loop for tree in (pg:expand-and-fill-n-times 50 :bottom
                                                    '(n oo (n oo x))
                                                    '(n oo (n oo (n oo x)))
                                                    '(n oo (n oo (n oo (n oo x)))))
         for i from 0
         collect `(nondestructive :tree ,tree
                                  :guidedp ,(zerop i)))))

(defun collapse ()
  `(exp:subsequence
    ,@(loop for tree in (pg:expand-and-fill-n-times 50 :bottom
                                                    '((n ** x) a (n ** x))
                                                    ;'((n ** x) aa x)
                                                    '(((n ** x) a (n ** x)) aa (n ** x))
                                                    ;'(((n ** x) aa x) aa (n ** x))
                                                    )
         for i from 0
         collect `(nondestructive :tree ,tree
                                  :guidedp ,(zerop i)))))

(defun switch ()
  `(exp:subsequence
    ,@(loop for tree in (pg:expand-and-fill-n-times 50 :bottom
                                                    '((n aa (n ** x)) aa (n ** x))
                                                    ;'((n aa (n ** x)) aa x)
                                                    ;'((n aa x) aa (n ** x))
                                                    )
         for i from 0
         collect `(nondestructive :tree ,tree
                                  :guidedp ,(zerop i)))))

(defun combine ()
  `(exp:subsequence
    ,@(loop for tree in (pg:expand-and-fill-n-times 50 :bottom
                                                    '((n ** (n ** x)) aa (n ** x))
                                                    ;'((n ** (n ** x)) aa x)
                                                    )
         for i from 0
         collect `(nondestructive :tree ,tree
                                  :guidedp ,(zerop i)))))

(defun reorder ()
  `(exp:subsequence
    ,@(loop for tree in (pg:expand-and-fill-n-times 50 :bottom
                                                    '((n ** (n aa (n ** x))) aa (n ** x))
                                                    ;'((n ** (n aa (n ** x))) aa x)
                                                    )
         for i from 0
         collect `(nondestructive :tree ,tree
                                  :guidedp ,(zerop i)))))
